package com.tools.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tools.ElasticsearchDao.PlayerELDao;
import com.tools.dao.PlayerDao;
import com.tools.entity.NBAPlayer;
import com.tools.service.PlayerService;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;


@Service
public class PlayerServiceImpl implements PlayerService {

    private static final Logger log = LoggerFactory.getLogger(PlayerServiceImpl.class);
    @Resource
    private RestHighLevelClient restHighLevelClient;
    @Resource
    private PlayerELDao playerELDao;
    @Resource
    private PlayerDao playerDao;

    private static final String NBA_INDEX = "nba";

    @Override
    public void addPlayer(NBAPlayer nbaPlayer, String id) throws IOException {
        String player_json = JSONObject.toJSONString(nbaPlayer);
        IndexRequest indexRequest = new IndexRequest(NBA_INDEX).id(id).source(JSONObject.parseObject(player_json,Map.class));
        IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        log.debug("插入数据返回结果[{}]", JSONObject.toJSONString(response));
    }

    @Override
    public NBAPlayer getPlayer(Integer id) throws IOException {
//        NBAPlayer nbaPlayer = playerELDao.findById(id).get();
        GetRequest getRequest = new GetRequest(NBA_INDEX,String.valueOf(id));
        GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
        Map<String, Object> source = response.getSource();
        NBAPlayer nbaPlayer = JSONObject.parseObject(JSONObject.toJSONString(source), NBAPlayer.class);
        return nbaPlayer;
    }

    @Override
    public void updatePlayer(NBAPlayer nbaPlayer, String id) throws IOException {
//        playerELDao.save(nbaPlayer);
        UpdateRequest updateRequest = new UpdateRequest(NBA_INDEX,id);
        updateRequest.doc(nbaPlayer,XContentType.JSON);
        restHighLevelClient.update(updateRequest,RequestOptions.DEFAULT);
    }

    @Override
    public void deleteAll() throws IOException {
        QueryWrapper<NBAPlayer> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id");
        List<NBAPlayer> list = playerDao.selectList(queryWrapper);
        BulkRequest bulkRequest = new BulkRequest();
        for (int i = 0; i < list.size(); i++) {
            NBAPlayer nbaPlayer = list.get(i);
            DeleteRequest deleteRequest = new DeleteRequest(NBA_INDEX,nbaPlayer.getId().toString());
            bulkRequest.add(deleteRequest);
        }
        restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
    }

    @Override
    public void deleteById(String id) throws IOException {
//        playerELDao.deleteById(Integer.valueOf(id));
        DeleteRequest deleteRequest = new DeleteRequest(NBA_INDEX,id);
        restHighLevelClient.delete(deleteRequest,RequestOptions.DEFAULT);
    }

    @Override
    public void importAll() throws IOException {
        List<NBAPlayer> nbaPlayers = playerDao.selectList(new QueryWrapper<>());
        playerELDao.saveAll(nbaPlayers);
        /*for(NBAPlayer nbaPlayer:nbaPlayers){
            addPlayer(nbaPlayer,nbaPlayer.getId().toString());
        }*/
    }

    @Override
    public List<NBAPlayer> termQuery(String name, String query) throws IOException {
        List<NBAPlayer> list = new ArrayList<>();
        SearchRequest request = new SearchRequest(NBA_INDEX);
        //构建查询器
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchPhraseQuery(name,query));
        builder.from(0);
        builder.size(100);
        request.source(builder);
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit:hits){
            NBAPlayer nbaPlayer = JSONObject.parseObject(hit.getSourceAsString(), NBAPlayer.class);
            list.add(nbaPlayer);
        }
        return list;
    }

    @Override
    public List<NBAPlayer> matchQuery(String name, String query) throws IOException {
        List<NBAPlayer> list = new ArrayList<>();
        SearchRequest request = new SearchRequest(NBA_INDEX);
        //构建查询器
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery(name,query));
        builder.from(0);
        builder.size(100);
        request.source(builder);
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit:hits){
            NBAPlayer nbaPlayer = JSONObject.parseObject(hit.getSourceAsString(), NBAPlayer.class);
            list.add(nbaPlayer);
        }
        return list;
    }
}
